import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";




// -------------------------Threejs部分内容-----------------
// 初始化场景
const scene = new THREE.Scene();

// 创建相机
// const camera = new THREE.PerspectiveCamera(
//   75, //视角
//   window.innerWidth / window.innerHeight, //宽高比
//   0.1, // 近平面
//   1000 // 远平面
// );
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100000);


// 设置相机位置
camera.position.set(5,5,5);
// 设置相机朝向点
camera.lookAt(0, 0, 0);


// 创建渲染器
const renderer = new THREE.WebGLRenderer({
//设置抗锯齿
antialias:true,
});
// 设置渲染器大小为窗口大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 添加到界面中
document.body.appendChild(renderer.domElement);


// 添加轨道控制器(控制的是相机)
const controls = new OrbitControls(camera, renderer.domElement);
// 设置带阻尼的惯性
controls.enableDamping = true;
// 设置阻尼系数，系数越小惯性越大
controls.dampingFactor = 0.05;

// 鼠标控制
controls.mouseButtons = {
//左键平移
LEFT: THREE.MOUSE.PAN,
//滚轮滑动
MIDDLE: THREE.MOUSE.DOLLY,
//右键旋转
RIGHT: THREE.MOUSE.ROTATE,
};

// AxesHelper：辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

//----------------------
// 添加具体的代码

// 构建一个从自定义材质的模型
let mesh = CreateCubeWithUV();
scene.add(mesh);


// NOTE:动态切换纹理效果
// // 定义纹理数组
// const textures = ['checker-map_tho.png', 'texture-map.png', 'uv_grid_opengl.jpg', 'uv-test-bw.png']; // 纹理图片路径
// let currentTextureIndex = 0;

// // 切换纹理的函数
// function switchTexture() {
//     currentTextureIndex = (currentTextureIndex + 1) % textures.length; // 计算下一个纹理的索引
//     const newTexturePath = "./texture/" +textures[currentTextureIndex];
//     console.log("Texture Path:",newTexturePath);

//     const texture = new THREE.TextureLoader().load(newTexturePath);
//     if(texture){
//         // 更新材质的纹理
//         if (mesh.material.map) {
//             mesh.material.map.dispose(); // 释放旧纹理内存
//         }
//         mesh.material.map = texture;
//         mesh.material.needsUpdate = true; // 通知 Three.js 材质已更新
//     }
//     else{
//         console.log("Texture is null");
//     }
    
// }

// // 每隔 1 秒切换一次纹理
// setInterval(switchTexture, 1000);










// 循环渲染

function render() {
controls.update();

// 每帧执行此函数
requestAnimationFrame(render);

// 渲染
renderer.render(scene, camera);

}

render();

// 监听窗口变化更新renderer
window.addEventListener("resize", () => {
// console.log("resize");
// 重置渲染器宽高比
renderer.setSize(window.innerWidth, window.innerHeight);
// 重置相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新相机投影矩阵
camera.updateProjectionMatrix();
});




function CreateCubeWithUV(){
    
    let vertexPointsArray=[
        0,0,0,
        1,0,0,
        1,0,1,
        0,0,1,
        0,1,0,
        1,1,0,
        1,1,1,
        0,1,1
    ];

    let indexArrays=[
        0,1,2,0,2,3,
        0,4,5,0,5,1,
        1,5,6,1,6,2,
        2,6,7,2,7,3,
        3,7,4,3,4,0,
        4,7,6,4,6,5
    ];

    // 定义 UV 坐标
    let uvArrays2 = CalculateUVArray(4,8);//构建4*4纹理图，顶点个数为8个


    let geometry = CreateGeometryWithUV(new Float32Array(vertexPointsArray), new Uint16Array(indexArrays), new Float32Array(uvArrays2));


    // const texture = new THREE.TextureLoader().load('./texture/uv_grid_opengl.jpg');
    const texture = CreateTextureWithValue();
    
    const material = new THREE.MeshBasicMaterial({ 
        map: texture ,
        side: THREE.DoubleSide
    });
    // console.log("material:",material);

    const mesh = new THREE.Mesh(geometry, material);

    return mesh;



}


function CreateGeometryWithUV(vertices,indices,uvs){
  
    // 创建 BufferGeometry
    const geometry = new THREE.BufferGeometry();
  
    // 设置顶点属性
    geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
  
    // 设置索引
    geometry.setIndex(new THREE.BufferAttribute(indices, 1));

    // 设置UV
    geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
  
    return geometry;  
}


function CalculateUVArray(imgSize, valueCount){
    const uvs = []; // 存储每个顶点的 UV 坐标

    for (let i = 0; i < valueCount; i++) {
        const x = i % imgSize; // x 像素坐标
        const y = Math.floor(i / imgSize); // y 像素坐标
        // 像素中心对齐：通过加 0.5 保证采样的是像素的中心，而不是边界
        const u = (x + 0.5) / imgSize; // 转换为 UV 的 u 坐标
        const v = 1 - (y + 0.5) / imgSize; // 转换为 UV 的 v 坐标
        

        uvs.push(u,v);
    }
    // console.log("uvs:", uvs);
    return uvs;
}


// NOTE:生成4*4的图片,写死的测试内容
function CreateTextureWithValue(){
    let valueData = [
        1,2,3,4,5,6,7,8
    ];
    const imgSize = 4;
    console.log("Create Image From Value Data.");

    return CreateImayerFromData(imgSize,valueData);
}


function CreateImayerFromData(imgSize,valueData){

    const size = imgSize; 
    const canvas = document.createElement('canvas');
    canvas.width = size;
    canvas.height = size;
    console.log("canvas:",canvas);

    const ctx = canvas.getContext('2d');

    const imageData = ctx?.createImageData(size, size); // 创建一个size*size的图像数据
    console.log("imageData length:",imageData?.data.length); //size*size*4 的数组

    // 假设顶点的数量小size*size，所以我们按顺序将valueData.length个温度值映射到128x128的图像
    // 将温度数据映射到图像像素上
    for (let i = 0; i < valueData.length; i++) {
        const value = valueData[i]; 

        // 计算图像像素的索引
        const x = i % size; // 计算x坐标
        const y = Math.floor(i / size); // 计算y坐标
        const index = (y * size + x) * 4; // 获取像素在图像数据中的位置

        if(value <= 3){
            imageData.data[index] = 255;     // R
            imageData.data[index + 1] = 0;   // G
            imageData.data[index + 2] = 0;   // B
            imageData.data[index + 3] = 255; // A
        }
        else if(value <=6 ){
            imageData.data[index] = 0; 
            imageData.data[index + 1] = 255;
            imageData.data[index + 2] = 0;
            imageData.data[index + 3] = 255;
        }
        else{
            imageData.data[index] = 0;     
            imageData.data[index + 1] = 0;
            imageData.data[index + 2] = 255;
            imageData.data[index + 3] = 255;
        }

    }

    // console.log("ImageData:",imageData);

    // 将图像数据绘制到canvas上
    ctx?.putImageData(imageData, 0, 0);

    // 保存纹理至本地
    // Canvas2Image(canvas,'temperature_map.png');

    // 创建纹理
    return new THREE.CanvasTexture(canvas);

}

function Canvas2Image(canvas, fileName) {
    // 默认保存为png格式
    const dataURL = canvas.toDataURL('image/png');

    const link = document.createElement('a');
    link.href = dataURL;
    link.download = fileName;

    document.body.appendChild(link);
    link.click();

    document.body.removeChild(link);

    return;
}